package pl;

import javacard.framework.ISO7816;
import javacard.framework.ISOException;
import javacard.framework.JCSystem;
import javacard.framework.Util;

public class DedicatedFile extends CardFile {

	private ElementaryFile[] elementaryFiles;
	private byte[] DfName;
	private byte firstEmptySlotForEF;

	public SecurityConditionByte createEf;
	public SecurityConditionByte deleteEf;
	public SecurityConditionByte createDf;
	
	public DedicatedFile(byte[] fid, byte[] name, byte elementaryFileNumber, byte[] access)
	{	
		super(fid, access);
		setAccessConditions(access);
		DfName = name;
		elementaryFiles = new ElementaryFile[elementaryFileNumber];
		// TODO: calc fci template size
		fciTemplate = new byte[(short)(2 + name.length + 2 + fid.length + 2 + 3 + 2 + access.length)];
		setFileDescriptorByte((byte)0x38);
	}
	
	public void setAccessConditions(byte[] acBytes) {
		
		byte index = 0;
		
		if ((acBytes[0] & 0x01) == 0x01)
		{
			index++;
			deleteEf = new SecurityConditionByte((byte) acBytes[index]);
		}
		else 
			deleteEf = new SecurityConditionByte((byte) 0xFF);
		
		if ((acBytes[0] & 0x02) == 0x02)
		{
			index++;
			createEf = new SecurityConditionByte((byte) acBytes[index]);
		}
		else
			createEf = new SecurityConditionByte((byte) 0xFF);
		
		if ((acBytes[0] & 0x04) == 0x04)
		{
			index++;
			createDf = new SecurityConditionByte((byte) acBytes[index]);
		}
		else
			createDf = new SecurityConditionByte((byte) 0xFF);

	}

	public void setElementaryFiles(ElementaryFile[] elementaryFiles) {
		this.elementaryFiles = elementaryFiles;
	}

	public ElementaryFile[] getElementaryFiles() {
		return elementaryFiles;
	}
	
	public void addElementaryFile(ElementaryFile ef)
	{
		if (findFirstEmptySlotForEf() == -1)
			ISOException.throwIt(ISO7816.SW_FILE_INVALID);
		
		JCSystem.beginTransaction();
		elementaryFiles[findFirstEmptySlotForEf()] = ef;
		JCSystem.commitTransaction();
	}

	public void setDfName(byte[] dfName) {
		Util.arrayCopy(dfName, MediatorFE.O, DfName,  MediatorFE.O, (short)dfName.length);
	}

	public byte[] getDfName() {
		return DfName;
	}
	
	public byte[] getFciTemplate()
	{
		fci.constructFciForDf(fciTemplate, this.getFid(), this.DfName, this.AccessCondtions);
		// 6F 17 83 025000 8C 020241 84 0DE828BD080F0147656D20503135 - df
		return fciTemplate;
	}
	
	public ElementaryFile findElementaryFile (byte[] fid)
	{
		for (short i = 0; i < getElementaryFiles().length; i++)
		{
			if (getElementaryFiles()[i] != null)
			{
				if (Util.arrayCompare(getElementaryFiles()[i].getFid(), (short)0, fid, (short)0, (short)2) == 0x00)
				{
					return getElementaryFiles()[i];
				}
			}
		}
		return null;
	}

	public byte findFirstEmptySlotForEf()
	{
		for (short i = 0; i < elementaryFiles.length; i++)
		{
			if (elementaryFiles[i] == null)
			{
				return (byte) i;
			}
		}
		return -1;
	}

}
